package com.etlmaster.executor.steps.load;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.util.StringUtils;

import com.etlmaster.core.DataSourceDefine;
import com.etlmaster.core.DataSourceHolder;
import com.etlmaster.executor.Step;
import com.etlmaster.executor.StepMeta;
import com.etlmaster.executor.annotation.StepInstruction;
import com.etlmaster.executor.utils.DataCollectionUtils;
import com.etlmaster.executor.utils.DpExecutorUtils;
import com.etlmaster.executor.utils.Shell;
import com.etlmaster.executor.utils.StepState;

/**
 * @author Wugf
 * @date 2016-03-08
 */
@StepInstruction("loadFile2Oracle")
public class LoadFileToOracleStep extends Step {

	private LoadFileToOracleStepMeta meta;

	public LoadFileToOracleStep(StepMeta meta) {
		super(meta);
		this.meta = (LoadFileToOracleStepMeta) meta;
	}

	@Override
	protected int handle() {
		String dsType = DataCollectionUtils.getDsType(meta.getDsName());
		if (!dsType.equalsIgnoreCase("oracle")) {
			meta.log("WARN", "选择非oracle数据库({})", meta.getDsName());
			return StepState.RUNNING_FAILED;
		}
		//字段为空会导致sqlldr在执行时，报语法错误
		if (StringUtils.isEmpty(meta.getColumns())) {
			meta.log("WARN", "选择字段为空,无法导入!");
			return StepState.RUNNING_FAILED;
		}
		DataSourceDefine def = DataSourceHolder.getInstance()
				.getDataSourceDefine(meta.getDsName());

		if (def != null) {
			meta.setUserName(def.getUsername());
			meta.setPassword(def.getPassword());
			if (def.getAlias()[0] != null) {
				meta.setAlias(def.getAlias()[0]);
				meta.log("WARN", "数据库{}别名为：{}", meta.getDsName(),
						meta.getAlias());
			} else {
				meta.log("WARN", "数据库{}别名为空，不能装载！", meta.getDsName());
				return StepState.RUNNING_FAILED;
			}
		} else {
			meta.log("WARN", "严重告警：未获取到 数据源{} (用户名{} 密码{} 本地别名{})未取到",
					meta.getDsName(), meta.getUserName(), meta.getPassword(),
					meta.getAlias());
			return StepState.RUNNING_FAILED;
		}
		if (meta.getDelimiter().equals("^A")) {
			meta.setDelimiter("0x01");
		} else if (meta.getDelimiter().equals("TAB")) {
			meta.setDelimiter("\t");
		} else if (meta.getDelimiter().equals("comma")) {
			meta.setDelimiter(",");
		}
		Shell.ShellCommandExecutor executor = new Shell.ShellCommandExecutor(
				new String[] {});
		String command = createLoadShellParams();
		meta.log("INFO", "执行load命令:{}" + command);
		try {
			executor.runCmd(command);
			int rtnFlag = executor.getExitCode();
			String logfileString = executor.getOutput();
			meta.log("INFO", "执行输出结果：{}", logfileString);
			if (rtnFlag == 0)
				return StepState.RUNNING_SUCCESSED;
			else
				return StepState.RUNNING_FAILED;
		} catch (Exception e) {
			meta.log("ERROR", "执行异常，{}", e.getMessage());
			return StepState.RUNNING_FAILED;
		}

	}

	private String createLoadShellParams() {
		String loadCmd = DataCollectionUtils.getProperties("oracle.loadCmd");
		Map<String, String> data = new HashMap<String, String>();
		StringBuilder params = new StringBuilder();
		String cmd = "";
		data.put("filePath", meta.getFilePath());
		data.put("table", meta.getTargetTable());
		data.put("mode", meta.getMode());
		data.put("delimiter", meta.getDelimiter());
		data.put("columns", meta.getColumns());
		data.put("userName", meta.getUserName());
		data.put("password", meta.getPassword());

		data.put("alias", meta.getAlias());

		cmd = DpExecutorUtils.variableSubstitution(loadCmd, data);
		try {
			File f = null;

			String logPath = DpExecutorUtils.getLogPath();
			meta.log("INFO", logPath);
			String fileName=meta.getFileName();
			if(fileName.length()==0){
				fileName=String.valueOf(this.hashCode());
			}
			f = writeToFile(cmd, "ctl", logPath, fileName);
			String filePath = f.getAbsolutePath();
			data.put("ctlfile", filePath);
		} catch (IOException e) {

			meta.log("ERROR", e.getMessage());
			meta.log("ERROR", "生成配置文件错误");
		}
		String loadShell = DpExecutorUtils.getSystemPath()
				+ DataCollectionUtils.getProperties("oracle.loadshell");
		loadShell = DpExecutorUtils.variableSubstitution(loadShell, data);
		String command = loadShell + " " + params.toString();
		return command;
	}

	@Override
	public boolean stop() {

		return false;
	}

	// /写批处理文件
	public static File writeToFile(String content, String suff,
			String parentPath, String fileName) throws IOException {

		File f = new File(parentPath, fileName + "." + suff);
		while (f.exists()) {
			f.delete();
		}
		f.createNewFile();
		FileOutputStream fos = new FileOutputStream(f);
		fos.write(content.toString().getBytes("UTF-8"));
		fos.close();
		return f;
	}
}
